package com.shen.langchain4j.controller;

import com.shen.langchain4j.service.McpChatAssistant;
import dev.langchain4j.mcp.McpToolProvider;
import dev.langchain4j.mcp.client.DefaultMcpClient;
import dev.langchain4j.mcp.client.McpClient;
import dev.langchain4j.mcp.client.transport.McpTransport;
import dev.langchain4j.mcp.client.transport.stdio.StdioMcpTransport;
import dev.langchain4j.model.chat.StreamingChatLanguageModel;
import dev.langchain4j.service.AiServices;
import dev.langchain4j.service.tool.ToolProvider;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import reactor.core.publisher.Flux;

import java.util.List;
import java.util.Map;


/**
 * http://localhost:18190/mcp/chatOne?question=查询61.149.121.66归属地
 * http://localhost:18190/mcp/chatOne?question=查询北京天气
 * http://localhost:18190/mcp/chatOne?question=查询昌平到天安门路线规划
 */
@Slf4j
@RestController
@RequestMapping("/mcp")
public class McpCallController {
    @Autowired
    private StreamingChatLanguageModel chatLanguageModel;

    /**
     * 基于MCP协议调用大模型
     *
     * @param question 问题
     * @return 流式输出
     */
    @GetMapping("/chatOne")
    public Flux<String> chatOne(@RequestParam(value = "question"
            , defaultValue = "今天天气怎么样") String question) {
        //1.构建MCP协议
        /**
         * 1.1 cmd：启动 Windows 命令行解释器。
         * 1.2 /c：告诉 cmd 执行完后面的命令后关闭自身。
         * 1.3 npx：npx = npm execute package，Node.js 的一个工具，用于执行 npm 包中的可执行文件。
         * 1.4 -y 或 --yes：自动确认操作（类似于默认接受所有提示）。
         * 1.5 @baidumap/mcp-server-baidu-map：要通过 npx 执行的 npm 包名
         * 1.6 BAIDU_MAP_API_KEY 是访问百度地图开放平台API的AK
         */
        McpTransport transport = new StdioMcpTransport.Builder()
                .command(List.of("cmd", "/c", "npx", "-y", "@baidumap/mcp-server-baidu-map"))
                .environment(Map.of("BAIDU_MAP_API_KEY", System.getenv("BAIDU_MAP_API_KEY")))
                .build();

        // 2.构建McpClient客户端
        McpClient mcpClient = new DefaultMcpClient.Builder()
                .transport(transport)
                .build();

        //3.创建工具集和原生的FunctionCalling类型
        ToolProvider toolProvider = McpToolProvider.builder()
                .mcpClients(mcpClient)
                .build();

        //4.通过AIServcies给我们接口McpService构建实现类并将工具集和大模型赋值给AIServices
        McpChatAssistant mcpChatAssistant = AiServices.builder(McpChatAssistant.class)
                .streamingChatLanguageModel(chatLanguageModel)
                .toolProvider(toolProvider).build();
        return mcpChatAssistant.chat(question);
    }

    @GetMapping("/chatTwo")
    public Flux<String> chatTwo(@RequestParam(value = "question"
            , defaultValue = "今天天气怎么样") String question) {
        McpChatAssistant normalAssistant = AiServices.builder(McpChatAssistant.class)
                .streamingChatLanguageModel(chatLanguageModel).build();
        return normalAssistant.chat(question);
    }
}
